import Foundation
import SwiftUI
import Alamofire
import CoreData
import Combine

struct ChatResponse: Codable {
    let choices: [ChatChoice]
}

struct ChatChoice: Codable {
    let message: ChatMessage
}

struct ChatMessage: Codable {
    let role: String
    let content: String
}

func chatWithGPT(inputText:String,context:NSManagedObjectContext, completion: @escaping (Bool) -> Void){
    
    var result:Bool = false
    var outputText:String = ""
    let apiKeyHeader = "Authorization"
    //old url let apiKeyValue = "Bearer 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"
    let apiKeyValue = "Bearer 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"
    let url = URL(string: "https://api.openai.com/v1/chat/completions")!
    
    let str = "请对如下语句中的时间，事件，金额，标签（收入或支出）和类型进行判断，其中金额必须以“元”为单位，且你返回的语句格式如下：“时间：time。事件：event。金额：amount。类型：type。标签：tag。”如果标签为支出，类型必须被识别为购物/理财/旅行/维修/学习/医疗/饮食/娱乐/运动；如果标签为收入，类型必须被识别为工资/奖学金/礼物/理财。例如“昨天买蛋糕花了20块钱”，则应该返回“时间：昨天。事件：吃蛋糕。金额：20元。类型：饮食。标签：支出。”。当任意变量缺失或无法正确识别时，返回语句为“未能正确识别。”"
    // 替换为您的预定义字符串
    let content = "\(str) \(inputText)"
    
    let message = [
        ["role": "system", "content": "You are a helpful assistant."],
        ["role": "user", "content": content]
    ]
    let parameters = ["model": "gpt-3.5-turbo", "messages": message] as [String: Any]
    
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.setValue(apiKeyValue, forHTTPHeaderField: apiKeyHeader)
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: [])
    
    URLSession.shared.dataTask(with: request) { data, response, error in
        if let data = data {
            if let decodedResponse = try? JSONDecoder().decode(ChatResponse.self, from: data) {
                DispatchQueue.main.async {
                    outputText = decodedResponse.choices[0].message.content
                    print(outputText)
                    
                    result = analyze(outputText: outputText, context: context)
                    completion(result)
                }
            }
        }
        completion(result)
        
    }.resume()
}


func analyze(outputText:String, context:NSManagedObjectContext)->Bool{
     var date: String = ""
     var name: String = ""
     var cost: String = ""
     var tag: String = ""
     var type: String = ""

     let dateRegexPattern = #"时间：(.*?)。"#

     let todayRegexPattern = #"今天"#
     let yesterdayRegexPattern = #"昨天"#
     let beforeYesterdayRegexPattern = #"前天"#
     let daysAgoRegexPattern = #"(\d+)天前"#
     let chineseNumberRegexPattern = #"([一二两三四五六七八九十]+)天前"#
    
     let yearRegexPattern = #"(?:(\d{4})年)?"#
     let monthRegexPattern = #"(\d{1,2})月"#
     let dayRegexPattern = #"(\d{1,2})(?:日|号)"#
     let lastYearRegexPattern = #"去年"#
     let lastYearMonthRegexPattern = #"去年(\d{1,2})月"#
     let lastYearMonthDayRegexPattern = #"去年(\d{1,2})月(\d{1,2})(?:日|号)"#
     let beforeLastYearRegexPattern = #"前年"#
     let beforeLastYearMonthRegexPattern = #"前年(\d{1,2})月"#
     let beforeLastYearMonthDayRegexPattern = #"前年(\d{1,2})月(\d{1,2})(?:日|号)"#
     let lastMonthRegexPattern = #"上个月"#
     let lastMonthDayRegexPattern = #"上个月(\d{1,2})(?:日|号)"#
     
       
     
     let nameRegexPattern = #"事件：(.*?)。"#
     let costRegexPattern = #"金额：(.*?)元。"#
     let tagRegexPattern = #"标签：(.*?)。"#
     let typeRegexPattern = #"类型：(.*?)。"#
     
    
     let notIdentified="未能正确识别"
     
     
                    
     if let dateRange = outputText.range(of: dateRegexPattern, options: .regularExpression),
        let nameRange = outputText.range(of: nameRegexPattern, options: .regularExpression),
        let costRange = outputText.range(of: costRegexPattern, options: .regularExpression),
        let tagRange = outputText.range(of: tagRegexPattern, options: .regularExpression),
        let typeRange = outputText.range(of: typeRegexPattern, options:
                .regularExpression){
         let nameMatch = outputText[nameRange]
         let tagMatch = outputText[tagRange]
         let costMatch = outputText[costRange]
         
         let nameString = String(nameMatch.dropFirst(3).dropLast(1))
         let tagString = String(tagMatch.dropFirst(3).dropLast(1))
         let costString = String(costMatch.dropFirst(3).dropLast(2))
         
         if nameString == notIdentified || tagString == notIdentified || costString == notIdentified{
             print("未识别到相关信息")
             return false
         }
         
         
         name = nameString
//         if let costValue = Double(String(costMatch.dropFirst(3).dropLast(2))) {
//             cost = String(costValue)
//         }
         tag = tagString
         
         let dateMatch = outputText[dateRange]
         let dateString = String(dateMatch.dropFirst(3)).trimmingCharacters(in: .punctuationCharacters)
         if dateString=="未能正确识别"{
             let dateFormatter = DateFormatter()
             dateFormatter.dateFormat = "yyyy年MM月dd日"
             date = dateFormatter.string(from: Date())
             print(date)
         }else if outputText.range(of: todayRegexPattern, options: .regularExpression) != nil {
             let dateFormatter = DateFormatter()
             dateFormatter.dateFormat = "yyyy年MM月dd日"
             date = dateFormatter.string(from: Date())
             print(date)
         } else if outputText.range(of: yesterdayRegexPattern, options: .regularExpression) != nil {
             let dateFormatter = DateFormatter()
             dateFormatter.dateFormat = "yyyy年MM月dd日"
             if let yesterday = Calendar.current.date(byAdding: .day, value: -1, to: Date()) {
                 date = dateFormatter.string(from: yesterday)
                 print(date)
             }
         } else if outputText.range(of: beforeYesterdayRegexPattern, options: .regularExpression) != nil {
             let dateFormatter = DateFormatter()
             dateFormatter.dateFormat = "yyyy年MM月dd日"
             if let beforeYesterday = Calendar.current.date(byAdding: .day, value: -2, to: Date()) {
                 date = dateFormatter.string(from: beforeYesterday)
                 print(date)
             }
         } else if let daysAgoRange = outputText.range(of: daysAgoRegexPattern, options: .regularExpression) {
             let daysAgoMatch = outputText[daysAgoRange]
             let daysAgoString = String(daysAgoMatch.dropLast(2))
             if let daysAgo = Int(daysAgoString) {
                 let dateFormatter = DateFormatter()
                 dateFormatter.dateFormat = "yyyy年MM月dd日"
                 if let dateAgo = Calendar.current.date(byAdding: .day, value: -daysAgo, to: Date()) {
                     date = dateFormatter.string(from: dateAgo)
                     print(date)
                 }
             }
         } else if let chineseNumberRange = outputText.range(of: chineseNumberRegexPattern, options: .regularExpression) {
             let chineseNumberMatch = outputText[chineseNumberRange]
             let chineseNumberString = String(chineseNumberMatch.dropLast(2))
             if let daysAgo = convertChineseNumberToDigit(chineseNumberString) {
                 let dateFormatter = DateFormatter()
                 dateFormatter.dateFormat = "yyyy年MM月dd日"
                 if let dateAgo = Calendar.current.date(byAdding: .day, value: -daysAgo, to: Date()) {
                     date = dateFormatter.string(from: dateAgo)
                     print(date)
                 }
             }
         }else if outputText.range(of: lastMonthRegexPattern, options: .regularExpression) != nil {
             let dateFormatter = DateFormatter()
             dateFormatter.dateFormat = "yyyy年MM月dd日"
             let currentDate = Date()
             let calendar = Calendar.current
             let currentYear = calendar.component(.year, from: currentDate)
             let currentMonth = calendar.component(.month, from: currentDate)
             let currentDay = calendar.component(.day, from: currentDate)
             
             var extractedDay: Int?
             
             if let dayRange = outputText.range(of: dayRegexPattern, options: .regularExpression) {
                 let dayMatch = outputText[dayRange]
                 let dayString = String(dayMatch.dropLast(1))
                 if let day = Int(dayString) {
                     extractedDay = day
                 }
             }
             
             var newDateComponents = DateComponents()
             
             if outputText.range(of: lastMonthDayRegexPattern, options: .regularExpression) != nil{
                 if(currentMonth == 1){
                    newDateComponents = DateComponents(year: currentYear-1, month: 12, day: extractedDay)
                 }else{
                    newDateComponents = DateComponents(year: currentYear, month: currentMonth-1, day: extractedDay)
                 }
             }else{
                 if(currentMonth == 1){
                    newDateComponents = DateComponents(year: currentYear-1, month: 12, day: currentDay)
                 }else{
                    newDateComponents = DateComponents(year: currentYear, month: currentMonth-1, day: currentDay)
                 }
             }
             
             date = dateFormatter.string(from: calendar.date(from: newDateComponents) ?? Date())
             print(date)
             
         }else if outputText.range(of: lastYearRegexPattern, options: .regularExpression) != nil {
             let dateFormatter = DateFormatter()
             dateFormatter.dateFormat = "yyyy年MM月dd日"
             let currentDate = Date()
             let calendar = Calendar.current
             let currentYear = calendar.component(.year, from: currentDate)
             let currentMonth = calendar.component(.month, from: currentDate)
             let currentDay = calendar.component(.day, from: currentDate)
             
             var extractedMonth: Int?
             var extractedDay: Int?
             
             
             if let monthRange = outputText.range(of: monthRegexPattern, options: .regularExpression) {
                 let monthMatch = outputText[monthRange]
                 let monthString = String(monthMatch.dropLast(1))
                 if let month = Int(monthString) {
                     extractedMonth = month
                 }
             }
             
             if let dayRange = outputText.range(of: dayRegexPattern, options: .regularExpression) {
                 let dayMatch = outputText[dayRange]
                 let dayString = String(dayMatch.dropLast(1))
                 if let day = Int(dayString) {
                     extractedDay = day
                 }
             }
             
             var newDateComponents = DateComponents()
             
             // 去年xx月xx日
             if outputText.range(of: lastYearMonthDayRegexPattern, options: .regularExpression) != nil{
                 newDateComponents = DateComponents(year: currentYear-1, month: extractedMonth, day: extractedDay)
                 
             }else if outputText.range(of: lastYearMonthRegexPattern, options: .regularExpression) != nil{
                 newDateComponents = DateComponents(year: currentYear-1, month: extractedMonth, day: currentDay)
             }else{
                 newDateComponents = DateComponents(year: currentYear-1, month: currentMonth, day: currentDay)
             }
             date = dateFormatter.string(from: calendar.date(from: newDateComponents) ?? Date())
             
             print(date)
             
             
         }else if outputText.range(of: beforeLastYearRegexPattern, options: .regularExpression) != nil {
             let dateFormatter = DateFormatter()
             dateFormatter.dateFormat = "yyyy年MM月dd日"
             let currentDate = Date()
             let calendar = Calendar.current
             let currentYear = calendar.component(.year, from: currentDate)
             let currentMonth = calendar.component(.month, from: currentDate)
             let currentDay = calendar.component(.day, from: currentDate)
             
            
             var extractedMonth: Int?
             var extractedDay: Int?
             
             
             if let monthRange = outputText.range(of: monthRegexPattern, options: .regularExpression) {
                 let monthMatch = outputText[monthRange]
                 let monthString = String(monthMatch.dropLast(1))
                 if let month = Int(monthString) {
                     extractedMonth = month
                 }
             }
             
             if let dayRange = outputText.range(of: dayRegexPattern, options: .regularExpression) {
                 let dayMatch = outputText[dayRange]
                 let dayString = String(dayMatch.dropLast(1))
                 if let day = Int(dayString) {
                     extractedDay = day
                 }
             }
             
             // 前年xx月xx日
             if outputText.range(of: beforeLastYearMonthDayRegexPattern, options: .regularExpression) != nil{
                 let newDateComponents = DateComponents(year: currentYear-2, month: extractedMonth, day: extractedDay)
                 date = dateFormatter.string(from: calendar.date(from: newDateComponents) ?? Date())
             }else if outputText.range(of: beforeLastYearMonthRegexPattern, options: .regularExpression) != nil{
                 let newDateComponents = DateComponents(year: currentYear-2, month: extractedMonth, day: currentDay)
                 date = dateFormatter.string(from: calendar.date(from: newDateComponents) ?? Date())
             }else{
                 let newDateComponents = DateComponents(year: currentYear-2, month: currentMonth, day: currentDay)
                 date = dateFormatter.string(from: calendar.date(from: newDateComponents) ?? Date())
             }
             
             
             print(date)
             
         }
         else {
             // 其他情况下，根据具体情况识别年份和月份
             let currentDate = Date()
             let calendar = Calendar.current
             let currentYear = calendar.component(.year, from: currentDate)
             let currentMonth = calendar.component(.month, from: currentDate)
             let currentDay = calendar.component(.day, from: currentDate)
             
             let dateFormatter = DateFormatter()
             dateFormatter.dateFormat = "yyyy年MM月dd日"
             
             
             
             var extractedYear: Int?
             var extractedMonth: Int?
             var extractedDay: Int?
             
             if let yearRange = outputText.range(of: yearRegexPattern, options: .regularExpression) {
                 let yearMatch = outputText[yearRange]
                 let yearString = String(yearMatch.dropLast(1))
                 if let year = Int(yearString) {
                     extractedYear = year
                 }
             }
             
             if let monthRange = outputText.range(of: monthRegexPattern, options: .regularExpression) {
                 let monthMatch = outputText[monthRange]
                 let monthString = String(monthMatch.dropLast(1))
                 if let month = Int(monthString) {
                     extractedMonth = month
                 }
             }
             
             if let dayRange = outputText.range(of: dayRegexPattern, options: .regularExpression) {
                 let dayMatch = outputText[dayRange]
                 let dayString = String(dayMatch.dropLast(1))
                 if let day = Int(dayString) {
                     extractedDay = day
                 }
             }
             
             if let year = extractedYear {
                 if let month = extractedMonth {
                     if let day = extractedDay {
                         // 年份、月份、日期均提取到
                         let newDateComponents = DateComponents(year: year, month: month, day: day)
                         if let newDate = calendar.date(from: newDateComponents) {
                             if newDate > currentDate {
                                 // 识别到的日期超过了当前日期，将其视为上个月的日期
                                 let previousMonthDate = calendar.date(byAdding: .month, value: -1, to: newDate)!
                                 date = dateFormatter.string(from: previousMonthDate)
                             } else {
                                 date = dateFormatter.string(from: newDate)
                             }
                             print(date)
                         }
                     } else {
                         // 只提取到年份和月份，日期使用当前日期
                         let newDateComponents = DateComponents(year: year, month: month, day: currentDay)
                         if let newDate = calendar.date(from: newDateComponents) {
                             if newDate > currentDate {
                                 // 识别到的日期超过了当前日期，将其视为上个月的日期
                                 let previousMonthDate = calendar.date(byAdding: .month, value: -1, to: newDate)!
                                 date = dateFormatter.string(from: previousMonthDate)
                             } else {
                                 date = dateFormatter.string(from: newDate)
                             }
                             print(date)
                         }
                     }
                 }else {
                     if let day = extractedDay {
                         // 只提取到年份和日期，月份使用当前月份
                         let newDateComponents = DateComponents(year: year, month: currentMonth, day: day)
                         if let newDate = calendar.date(from: newDateComponents) {
                             date = dateFormatter.string(from: newDate)
                             print(date)
                         }
                     } else {
                         // 只提取到年份，月份和日期均使用当前日期
                         let newDateComponents = DateComponents(year: year, month: currentMonth, day: currentDay)
                         if let newDate = calendar.date(from: newDateComponents) {
                             date = dateFormatter.string(from: newDate)
                             print(date)
                         }
                     }
                 }
             } else {
                 if let month = extractedMonth {
                     if let day = extractedDay {
                         // 只提取到月份和日期，年份根据当前日期判断
                         let newYear: Int
                         if currentMonth < month || (currentMonth == month && currentDay < day) {
                             newYear = currentYear - 1
                         } else {
                             newYear = currentYear
                         }
                         let newDateComponents = DateComponents(year: newYear, month: month, day: day)
                         if let newDate = calendar.date(from: newDateComponents) {
                             date = dateFormatter.string(from: newDate)
                             print(date)
                         }
                     } else {
                         // 只提取到月份，日期使用当前日期，年份根据当前日期判断
                         let newYear: Int
                         if currentMonth < month {
                             newYear = currentYear - 1
                         } else {
                             newYear = currentYear
                         }
                         let newDateComponents = DateComponents(year: newYear, month: month, day: currentDay)
                         if let newDate = calendar.date(from: newDateComponents) {
                             date = dateFormatter.string(from: newDate)
                             print(date)
                         }
                     }
                 } else {
                     // 只提取到日期，使用当前日期的年份和月份
                     let newDateComponents = DateComponents(year: currentYear, month: currentMonth, day: extractedDay)
                     if let newDate = calendar.date(from: newDateComponents) {
                         if newDate > currentDate {
                             // 识别到的日期超过了当前日期，将其视为上个月的日期
                             let previousMonthDate = calendar.date(byAdding: .month, value: -1, to: newDate)!
                             date = dateFormatter.string(from: previousMonthDate)
                         } else {
                             date = dateFormatter.string(from: newDate)
                         }
                         print(date)
                     }
                     
                 }
             }
         }
         
         //                            let eventMatch = outputText[eventRange]
         //                            event = String(eventMatch.dropFirst(3).dropLast(1))
         //
         //                            let amountMatch = outputText[amountRange]
         //                            if let amountValue = Double(String(amountMatch.dropFirst(3).dropLast(2))) {
         //                                amount = amountValue
         //                            }
         //
         //                            let typeMatch = outputText[typeRange]
         //                            type = String(typeMatch.dropFirst(3).dropLast(1))
         
         let typeMatch = outputText[typeRange]
         let typeString = String(typeMatch.dropFirst(3).dropLast(1))
         if typeString=="未能正确识别"{
             type="其他"
         }else{
             type=typeString
         }
         
         print(date)

         
         do{
             let newBill = BillDetail(context: context)
             newBill.name = name
             newBill.type = type
             newBill.date = convertStringToDate(date)
             print (newBill.date)
             if(tag=="收入"){
                 newBill.tag = true
             }else{
                 newBill.tag = false
             }
             newBill.cost = Double(costString) ?? 0.0
             
            /* print("日期：\(date)")
             print("事件：\(name)")
             print("金额：\(cost)")
             print("收支：\(tag)")
             print("类型：\(type)")
             */
             try context.save()
         }catch{
             //Do Action
             print(error.localizedDescription)
         }
         return true
     }
    return false
 }



// 辅助函数，将汉字数字转换为对应的数字值
func convertChineseNumberToDigit(_ chineseNumber: String) -> Int? {
    let digitMap: [Character: Int] = ["零": 0, "一": 1, "二": 2, "三": 3, "四": 4, "五": 5, "六": 6, "七": 7, "八": 8, "九": 9, "十": 10]
    
    var result: Int = 0
    var currentNumber: Int = 0
    
    for character in chineseNumber {
        if let digit = digitMap[character] {
            if digit == 10 {
                if currentNumber == 0 {
                    currentNumber = 10
                } else {
                    currentNumber *= 10
                }
            } else {
                currentNumber += digit
            }
        } else {
            return nil
        }
    }
    
    result += currentNumber
    
    return result
}

// 添加计算指定周几日期的方法
func calculateWeekdayDateZ(_ weekdayString: String, from date: Date) -> Date? {
    let calendar = Calendar.current
    
    let weekdaySymbols = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"]
    
    let weekdayIndex = weekdaySymbols.firstIndex(of: weekdayString)
    
    guard let index = weekdayIndex else {
        return nil
    }

    let currentWeekdayIndex = calendar.component(.weekday, from: date) - 1
    
    var daysToAdd = index - currentWeekdayIndex
    
    if daysToAdd > 0 {
        daysToAdd += 7
    }
    
    let weekdayDate = calendar.date(byAdding: .day, value: daysToAdd, to: date)
    
    return weekdayDate
}

// 添加计算指定星期几日期的方法
func calculateWeekdayDateXQ(_ weekdayString: String, from date: Date) -> Date? {
    let calendar = Calendar.current
    
    let weekdaySymbols = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]
    
    let weekdayIndex = weekdaySymbols.firstIndex(of: weekdayString)
    
    guard let index = weekdayIndex else {
        return nil
    }

    let currentWeekdayIndex = calendar.component(.weekday, from: date) - 1
    
    var daysToAdd = index - currentWeekdayIndex
    
    if daysToAdd > 0 {
        daysToAdd += 7
    }
    
    let weekdayDate = calendar.date(byAdding: .day, value: daysToAdd, to: date)
    
    return weekdayDate
}

// 添加计算指定上周几日期的方法
func calculateLastWeekdayDateZ(_ weekdayString: String, from date: Date) -> Date? {
    let calendar = Calendar.current
    
    let weekdaySymbols = ["上周日", "上周一", "上周二", "上周三", "上周四", "上周五", "上周六"]
    
    let weekdayIndex = weekdaySymbols.firstIndex(of: weekdayString)
    
    guard let index = weekdayIndex else {
        return nil
    }
    
    let currentWeekdayIndex = calendar.component(.weekday, from: date) - 1
    
    var daysToAdd = 0
    
    if currentWeekdayIndex == 0{
        daysToAdd = index - currentWeekdayIndex
    }else{
        daysToAdd = index - currentWeekdayIndex - 7
    }
    
    
    let lastWeekdayDate = calendar.date(byAdding: .day, value: daysToAdd, to: date)
    
    return lastWeekdayDate
}

// 添加计算指定上星期几日期的方法
func calculateLastWeekdayDateXQ(_ weekdayString: String, from date: Date) -> Date? {
    let calendar = Calendar.current
    
    let weekdaySymbols = ["上星期日", "上星期一", "上星期二", "上星期三", "上星期四", "上星期五", "上星期六"]
    
    let weekdayIndex = weekdaySymbols.firstIndex(of: weekdayString)
    
    guard let index = weekdayIndex else {
        return nil
    }
    
    let currentWeekdayIndex = calendar.component(.weekday, from: date) - 1
    
    var daysToAdd = 0
    
    if currentWeekdayIndex == 0{
        daysToAdd = index - currentWeekdayIndex
    }else{
        daysToAdd = index - currentWeekdayIndex - 7
    }
    
    let lastWeekdayDate = calendar.date(byAdding: .day, value: daysToAdd, to: date)
    
    return lastWeekdayDate
}

func convertStringToDate(_ dateString: String) -> Date {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy年MM月dd日"
    dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)  // 设置时区为UTC
    
    return dateFormatter.date(from: dateString) ?? .init()
    
}




